#include "bsp_https.h"
#include <sys/param.h>
#include <stdlib.h>
#include <ctype.h>
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_netif.h"
// #include "protocol_examples_common.h"
// #include "protocol_examples_utils.h"
#include "esp_tls.h"
#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
#include "esp_crt_bundle.h"
#endif

#if !CONFIG_IDF_TARGET_LINUX
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#endif

#include "esp_http_client.h"
#include "bsp_blufi.h"
#include "cJSON.h"
#include "bsp_nvs.h"
#define MAX_HTTP_RECV_BUFFER 512
#define MAX_HTTP_OUTPUT_BUFFER 2048

static const char *TAG = "HTTP_CLIENT";
/*****************************************************/
/***********************HTTP***************************/
/*****************************************************/
#define HTTPS_WEB "https://new-uat-api.yjt.com.cn/backend/mqttInfo/dev"
https_get_info_t https_get_info = {0};
static uint8_t https_connected_flag = 0;
cJSON* cjson_send = NULL;
char* str = NULL;
void post_json_bulid()
{
    nvs_info_t *https_device_id_info = get_nvs_info();
    cjson_send = cJSON_CreateObject();
    cJSON_AddStringToObject(cjson_send, "deviceCode", https_device_id_info->device_id);
    cJSON_AddStringToObject(cjson_send, "productCode", "CL1");
    str = cJSON_Print(cjson_send);

}

void https_parse_rx_data(char *buffer)
{
    cJSON* cjson_rx = NULL;
    /* 解析整段JSON数据 */
    cjson_rx = cJSON_Parse(buffer);
    if(cjson_rx == NULL){
        cJSON_Delete(cjson_rx);
        return;
    }
    cJSON* cjson_rec_host = cJSON_GetObjectItem(cjson_rx, "host");
    cJSON* cjson_rec_port = cJSON_GetObjectItem(cjson_rx, "port");
    cJSON* cjson_rec_user = cJSON_GetObjectItem(cjson_rx, "user");
    cJSON* cjson_rec_pwd = cJSON_GetObjectItem(cjson_rx, "pwd");
    cJSON* cjson_rec_d2s = cJSON_GetObjectItem(cjson_rx, "d2sTopics");
    cJSON* cjson_rec_u2d = cJSON_GetObjectItem(cjson_rx, "u2dTopic");
    cJSON* cjson_rec_d2u = cJSON_GetObjectItem(cjson_rx, "d2uTopic");
    cJSON* cjson_rec_s2d = cJSON_GetObjectItem(cjson_rx, "s2dTopic");
    cJSON* cjson_rec_clientId = cJSON_GetObjectItem(cjson_rx, "clientId");

    if(cjson_rec_host != NULL){
        memcpy(https_get_info.host, cjson_rec_host->valuestring, strlen(cjson_rec_host->valuestring));
    }
    if(cjson_rec_port != NULL){
        https_get_info.port = cjson_rec_port->valueint;
    }
    if(cjson_rec_user != NULL){
        memcpy(https_get_info.user, cjson_rec_user->valuestring, strlen(cjson_rec_user->valuestring));
    }
    if(cjson_rec_pwd != NULL){
        memcpy(https_get_info.pwd, cjson_rec_pwd->valuestring, strlen(cjson_rec_pwd->valuestring));
    }
    if(cjson_rec_d2s != NULL){
        char *pStr = NULL;
        cJSON * ArrStrEle = cJSON_GetArrayItem(cjson_rec_d2s, 0);
        if(NULL != ArrStrEle){
            pStr = cJSON_GetStringValue(ArrStrEle);
        }
	    memcpy(https_get_info.d2s, pStr, strlen(pStr));
    }
    if(cjson_rec_u2d != NULL){
        memcpy(https_get_info.u2d, cjson_rec_u2d->valuestring, strlen(cjson_rec_u2d->valuestring));
    }
    if(cjson_rec_d2u != NULL){
        memcpy(https_get_info.d2u, cjson_rec_d2u->valuestring, strlen(cjson_rec_d2u->valuestring));
    }
    if(cjson_rec_s2d != NULL){
        memcpy(https_get_info.s2d, cjson_rec_s2d->valuestring, strlen(cjson_rec_s2d->valuestring));
    }
    if(cjson_rec_clientId != NULL){
        memcpy(https_get_info.clientId, cjson_rec_clientId->valuestring, strlen(cjson_rec_clientId->valuestring));
        https_connected_flag = 1;
    }

    /* 清除cjson申请的内存 */
    cJSON_Delete(cjson_rx);

}

esp_err_t _http_event_handler(esp_http_client_event_t *evt)
{
    static char recbuffer[500] = {0};
    static uint16_t rec_length = 0;
    switch(evt->event_id) {
        case HTTP_EVENT_ERROR:
            ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
            break;
        case HTTP_EVENT_ON_CONNECTED:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
            
            break;
        case HTTP_EVENT_HEADER_SENT:
            ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
            break;
        case HTTP_EVENT_ON_HEADER:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
            break;
        case HTTP_EVENT_ON_DATA:
            // ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
            if (!esp_http_client_is_chunked_response(evt->client)) {
                memcpy(recbuffer+rec_length, evt->data, evt->data_len);
                rec_length += evt->data_len;
            }
            
            break;
        case HTTP_EVENT_ON_FINISH:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
            break;
        case HTTP_EVENT_DISCONNECTED:
            ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
            recbuffer[rec_length] = '\0';
            https_parse_rx_data(recbuffer);
            rec_length = 0;
            memset(recbuffer,0,sizeof(recbuffer));
            break;
        case HTTP_EVENT_REDIRECT:
            ESP_LOGD(TAG, "HTTP_EVENT_REDIRECT");
            break;
    }
    return ESP_OK;
}

void http_rest_with_url()
{
    esp_err_t err;
    esp_http_client_config_t config = {
        .url = HTTPS_WEB,
        .transport_type = HTTP_TRANSPORT_OVER_TCP,
        .event_handler = _http_event_handler,
        .skip_cert_common_name_check = true,

    };
    esp_http_client_handle_t client = esp_http_client_init(&config);
    printf("after esp_http_client_init\n");
    // POST
    esp_http_client_set_method(client, HTTP_METHOD_POST);
    esp_http_client_set_header(client, "Content-Type", "application/json");
    printf("after esp_http_client_set_header\n");
    esp_http_client_set_post_field(client, str, strlen(str));
    err = esp_http_client_perform(client); 
    if (err == ESP_OK) {
        ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %"PRIu64,
                esp_http_client_get_status_code(client),
                esp_http_client_get_content_length(client));
    } else {
        ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
    }
    esp_http_client_cleanup(client);

}

extern void mqtt_task(void *pvParameters);
void http_task(void *pvParameters)
{
    post_json_bulid();
    for(;;){
        if(gl_sta_got_ip == true){
            vTaskDelay(500/portTICK_PERIOD_MS);
            if(https_connected_flag == 0){
                http_rest_with_url();
            }else{
                /* 获取到https信息 */
                xTaskCreate(&mqtt_task, "mqtt_task", 8192, NULL, 10, NULL);
                vTaskDelete(NULL);
            }
        }else{
            https_connected_flag = 0;
        }
        vTaskDelay(500/portTICK_PERIOD_MS);

    }

}



